/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */

#ifndef __BLENDER_MATERIAL_LOADER_H__
#define __BLENDER_MATERIAL_LOADER_H__

#include "GPrerequisites.h"

#include "blender.h"
#include "bMain.h"
#include "bBlenderFile.h"

#include "OgreGpuProgram.h"
#include "OgreMaterial.h"

namespace GNgine
{
	enum TextureLayers
	{
		// six layers by default in ogre, see OGRE_MAX_TEXTURE_COORD_SETS
		// blender has eight
		TL_UV0=0,
		TL_UV1,
		TL_UV2,
		TL_UV3,
		TL_UV4,
		TL_UV5,
		TL_UV6,
		TL_UV7,
	};

	typedef std::vector<Blender::MTex*> MTexList;

	class BlenderTextureLoader;

	class BlenderMaterialLoader
	{
		typedef std::map<Blender::Image*,Ogre::Texture*> ImageTextureMap;
		typedef std::vector<Ogre::Texture*> TextureList;
		typedef std::vector<BlenderTextureLoader*> TextureLoaderList;

	public:
		BlenderMaterialLoader(Ogre::String group,bParse::bBlenderFile* blenderFile);
		~BlenderMaterialLoader();

		void getOgreMaterialFromMaterial(Ogre::MaterialPtr ptr, Blender::Material *matr, Blender::Mesh *me, int flags);
		void setOgreMaterialDefault(Ogre::MaterialPtr ptr, bool lighting, int flags, int alpha);

		void addTextureUnit(Ogre::MaterialPtr materialPtr, Blender::Image *bImage, int layerIndex);
		void addBlenderImage(Blender::Image* bImage);
	private:
		void handleMultiPass(void);
		void handleStd(void);

		void applyAmbientPass(void);
		void applyLightPass(void);
		void applyTexturePass(void);
		bool applyTexFace(int flags, int alpha);

		bool hasLamp(void);

		Ogre::Pass *getOrCreatePass(size_t idx);

		int getNumTextures(void);
		Blender::MTex* getTexture(size_t i);
		Blender::MTex* getTexture(int mapto, int fallback);
		MTexList getTextures(int mapto);

		int getUVLayer(Blender::MTex *te);

		Ogre::String getSpecularDef(void);
		Ogre::String getDiffuseDef(void);

		Ogre::TextureUnitState* addTextureUnit(Ogre::Pass* ptr, Blender::MTex *tex);
		Ogre::TextureUnitState* addTextureUnit(Ogre::Pass* pass, Blender::Image *bImage, int layerIndex);

		void applyParameters(Ogre::GpuProgramParametersSharedPtr params);
	private:
		bParse::bBlenderFile* _bFile;// current blender file
		Blender::Material* _bMaterial;// blender ptr
		Blender::Mesh* _bMesh; // owner mesh
		MTexList _bTextures;

		Ogre::String _group;
		Ogre::Material* _material;
		Ogre::Technique* _tech; // current technique
		Ogre::Pass* _pass;// current pass

		ImageTextureMap _bImageLookup;
		TextureList _textures;

		bool _multiPass;// use multi pass shaders (WIP)
		bool _isModern;//multi pass supported ?
	};



}

#endif
